// 实现数组和对象的深拷贝
// function deepCopy(obj) {
//   // 只拷贝数组和对象
//   if (!obj || typeof obj !== 'object') {
//     return obj;
//   }
//   // 根据输入类型判断新建一个数组还是对象
//   let newObj = Array.isArray(obj) ? [] : {};
//   // 遍历object,并且判断是否属于自己的属性才拷贝
//   for (let key in obj) {
//     if (obj.hasOwnProperty(key)) {
//       // 判断属性值是否是数组或者对象 如果是继续深层的拷贝。
//       // 这就是与浅拷贝不同的地方
//       newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
//     }
//   }
//   return newObj;
// }

// // 测试
// var obj = {
//   id: 1,
//   name: 'andy',
//   msg: {
//     age: 18
//   },
//   color: ['pink', 'red']
// };

// var objcopy = deepCopy(obj)
// console.log(obj);
// objcopy.msg.age = 20;
// console.log(objcopy);
// console.log(obj);

// 实现循环引用的拷贝
function deepCopy(obj, map = new Map()) {
  if (!obj || typeof obj !== 'object') {
    return obj;
  }
  // 用来判断是否之前有拷贝过obj 就不会无限递归，直接返回
  if (map.has(obj)) {
    return map.get(obj);
  }
  // 没有的话 就设置键 值
  let newObj = Array.isArray(obj) ? [] : {};
  // 对象是引用类型 属性变了  map里面的也会变
  map.set(obj, newObj);
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepCopy(obj[key], map);
    }
  }
  console.log(map);
  return newObj;
}

const obj = {
  name: "muyiy",
  a1: undefined,
  a2: null,
  a3: 123,
  book: { title: "You Don't Know JS", price: "45" },
}
// 这里是循环引用
obj.circleRef = obj

let objCopy = deepCopy(obj);
console.log(objCopy);

